package com.school.common.intereceptor;

import cn.hutool.core.bean.BeanUtil;
import com.school.common.LoginConstants;
import com.school.common.UserConstants;
import com.school.common.utils.UserHolder;
import com.school.config.JwtUtils;
import com.school.domain.vo.user.LoginVO;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;


@Slf4j
public class UserInterceptor implements HandlerInterceptor {

    private final JwtUtils jwtUtils;
    private final StringRedisTemplate stringRedisTemplate;

    public UserInterceptor(JwtUtils jwtUtils, StringRedisTemplate stringRedisTemplate) {
        this.jwtUtils = jwtUtils;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 判断是否需要拦截,判断token
        String token = request.getHeader(LoginConstants.TOKEN_HEADER);
        log.debug("token: {} ", token);
        String s = stringRedisTemplate
                .opsForValue()
                .get(UserConstants.USER_TOKEN + token);

        if (s != null) {
            response.setStatus(401);
            return false;
        }
        //claims看了源码，可以看做Map子类的子类，根据子类能代表父类的规则，所以claims可以看做为Map
        //由于本身这个令牌的校验方式就是进行解密是否报错来确定，故而进行了二合一
        Claims claims = jwtUtils
                .validateAndParseToken(token);
//        System.err.println("claims:" + claims);
        if (BeanUtil.isEmpty(claims)) {
            response.setStatus(401);
            return false;
        }
        LoginVO user = BeanUtil
                .toBean(claims
                        .get(LoginConstants.TOKEN_PREFIX), LoginVO.class);
        UserHolder.saveUser(user);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {
        UserHolder.removeUser();
    }
}
